/*
 * 在本节中，您将学习Orchard Core如何使用称为形状（shapes）的可重用组件在UI上显示各种信息
 * （请参阅：https://docs.orchardcore.net/en/latest/docs/reference/core/Placement/#shapes）。
 * 这是Orchard Core中一个非常大且强大的部分，在这里您将学习显示管理的基础知识。
 *
 * 为了演示这个基本功能，我们将创建两个稍微不同的页面来显示关于书籍的信息。
 * 
 * 主要功能：
 * - 演示Orchard Core显示管理系统
 * - 展示形状（shapes）的使用
 * - 演示显示管理器的使用
 * - 展示不同显示类型的应用
 */

using Lombiq.TrainingDemo.Models;
using Microsoft.AspNetCore.Mvc;
using OrchardCore.DisplayManagement;
using OrchardCore.DisplayManagement.ModelBinding;
using System.Threading.Tasks;

namespace Lombiq.TrainingDemo.Controllers;

/// <summary>
/// 显示管理控制器 - 演示Orchard Core显示管理系统
/// 
/// 主要用途：
/// - 演示Orchard Core显示管理系统
/// - 展示形状（shapes）的使用
/// - 演示显示管理器的使用
/// - 展示不同显示类型的应用
/// 
/// 使用场景：
/// - 创建临时形状
/// - 构建书籍显示形状
 /* - 使用不同显示类型
 * - 演示显示管理的基础功能
 * 
 * 设计原因：
 * - 展示Orchard Core显示系统的强大功能
 * - 演示形状的可重用性
 * - 提供显示管理的最佳实践
 * - 展示显示类型的灵活性
 * 
 * 设计模式：
 * - 显示模式：使用IDisplayManager构建显示形状
 * - 依赖注入模式：通过构造函数注入显示管理器
 * - 形状模式：使用形状作为可重用组件
 * - 模型绑定模式：实现IUpdateModel接口
 */
/// </summary>
public sealed class DisplayManagementController : Controller, IUpdateModel
{
    // 核心显示管理功能可以通过IDisplayManager服务使用。泛型参数将是需要以某种方式在UI上显示的对象。
    // 不要忘记在服务提供程序中注册这个泛型类（请参阅：Startup.cs）。
    private readonly IDisplayManager<Book> _bookDisplayManager;

    /// <summary>
    /// 构造函数 - 注入显示管理器
    /// </summary>
    /// <param name="bookDisplayManager">书籍显示管理器，用于构建书籍显示形状</param>
    public DisplayManagementController(IDisplayManager<Book> bookDisplayManager) => _bookDisplayManager = bookDisplayManager;

    /// <summary>
    /// 临时形状演示
    /// 
    /// 功能说明：
    /// - 演示如何创建临时形状
    /// - 展示形状的基本概念
    /// - 演示形状的创建方式
    /// 
    /// 访问方式：
    /// - URL：/Lombiq.TrainingDemo/DisplayManagement/AdHocShape
    /// </summary>
    /// <returns>返回临时形状演示视图</returns>
    // 在我们学习如何使用显示管理器生成形状之前，让我们看看这些形状实际上是什么。
    // 临时形状可以在没有显示管理器的情况下在任何地方创建。在这个示例中，我们将看到如何在视图（或可能是另一个形状）内创建临时形状。
    // 稍后我们还将看到如何从过滤器中也这样做。从/Lombiq.TrainingDemo/DisplayManagement/AdHocShape下打开。
    public ActionResult AdHocShape() => View();

    // 下一站：Views/DisplayManagement/AdHocShape.cshtml

    /// <summary>
    /// 显示书籍信息
    /// 
    /// 功能说明：
    /// - 创建书籍对象用于演示
    /// - 使用显示管理器构建显示形状
    /// - 展示书籍信息的显示方式
    /// 
    /// 显示过程：
    /// - 创建演示书籍对象
    /// - 使用显示管理器生成形状
    /// - 将形状传递给视图进行渲染
    /// 
    /// 访问方式：
    /// - URL：/Lombiq.TrainingDemo/DisplayManagement/DisplayBook
    /// </summary>
    /// <returns>返回书籍显示视图</returns>
    // 首先，创建一个页面来显示书籍的摘要和一些附加数据。在/Lombiq.TrainingDemo/DisplayManagement/DisplayBook下查看它。
    public async Task<IActionResult> DisplayBook()
    {
        // 为了演示目的创建一个虚拟书籍对象。
        var book = CreateDemoBook();

        // 这个方法将生成一个主要用于显示给定对象信息的形状。
        var shape = await _bookDisplayManager.BuildDisplayAsync(book, this);

        // 我们将看到这个显示形状是如何生成的以及它将包含什么，但首先让我们看看这是如何在MVC视图中渲染的。
        // 下一站：转到Views/DisplayManagement/DisplayBook.cshtml。

        return View(shape);
    }

    /// <summary>
    /// 显示书籍描述
    /// 
    /// 功能说明：
    /// - 使用特定显示类型生成书籍显示形状
    /// - 演示显示类型的使用
    /// - 展示不同显示类型的应用
    /// 
    /// 显示类型：
    /// - 使用"Description"显示类型
    /// - Orchard Core将搜索名为[ClassName].[DisplayType].cshtml的cshtml文件
    /// - 提供更具体的显示方式
    /// 
    /// 访问方式：
    /// - URL：/Lombiq.TrainingDemo/DisplayManagement/DisplayBookDescription
    /// </summary>
    /// <returns>返回书籍描述显示视图</returns>
    // 让我们生成另一个Book显示形状，但现在使用显示类型。在/Lombiq.TrainingDemo/DisplayManagement/DisplayBookDescription下查看它。
    public async Task<IActionResult> DisplayBookDescription()
    {
        // 生成另一个用于演示目的的书籍对象。
        var book = CreateDemoBook();

        // 这次给出一个附加参数，即显示类型。如果给出显示类型，那么Orchard Core将搜索名为[ClassName].[DisplayType].cshtml的cshtml文件。
        var shape = await _bookDisplayManager.BuildDisplayAsync(book, this, "Description");

        // 下一站：转到Views/Book.Description.cshtml

        return View(shape);
    }

    /// <summary>
    /// 创建演示书籍对象
    /// 
    /// 功能说明：
    /// - 创建用于演示的书籍对象
    /// - 包含完整的书籍信息
    /// - 提供测试数据
    /// 
    /// 书籍信息：
    /// - 标题：Harry Potter and The Sorcerer's Stone
    /// - 作者：J.K. (Joanne) Rosenzweig
    /// - 封面图片：/Lombiq.TrainingDemo/images/HarryPotter.jpg
    /// - 描述：关于哈利波特的故事
    /// </summary>
    /// <returns>演示书籍对象</returns>
    private static Book CreateDemoBook() =>
        new()
        {
            CoverPhotoUrl = "/Lombiq.TrainingDemo/images/HarryPotter.jpg",
            Title = "Harry Potter and The Sorcerer's Stone",
            Author = "J.K. (Joanne) Rosenzweig",
            Description = "Harry hasn't had a birthday party in eleven years - but all that is about to change " +
                "when a mysterious letter arrives with an invitation to an incredible place.",
        };
}

// 如果您已经完成了两个操作（以及它们的.cshtml文件），那么您可以继续下一个训练。

// 训练部分结束：显示管理

// 下一站：Controllers/DatabaseStorageController
